    const PENDING = 'pending'
	const FULILLED = 'fullilled'
	const REJECTED = 'rejected'

	class mypromise {
		
		constructor(executor) {
			try{
			    executor(this.resolve,this.reject)
			}catch(e){
				this.reject(e)
			}
		 
		}
		
		status = PENDING
		value = undefined
		reason = undefined
		successCallback = []
		failCallback = []
		
		resolve = value =>{
			if(this.status !== PENDING) return 
			this.status = FULILLED
			this.value = value
			while(this.successCallback.length) this.successCallback.shift()()
		}
		
		reject = reason =>{
			if(this.status !== PENDING) return 
			this.status = REJECTED
			this.reason = reason
			while(this.failCallback.length) this.failCallback.shift()()
		}
		
		then(successCallback,failCallback){
			
			successCallback = successCallback ? successCallback : value => value
			failCallback = failCallback ? failCallback : reason => { throw reason }
			let promise2 = new mypromise((resolve,reject)=>{
				if(this.status === FULILLED){
					setTimeout(()=>{
						try{
							let x = successCallback(this.value)
				            resolvePromise(promise2,x,resolve,reject)
						}catch(e){
							reject(e)
						}
					
					},0)   
			}else if(this.status === REJECTED){
				   setTimeout(()=>{
				   	try{
				   		let x = failCallback(this.reason)
				           resolvePromise(promise2,x,resolve,reject)
				   	}catch(e){
				   		reject(e)
				   	}
				   
				   },0)   
			}else{
				this.successCallback.push(()=>{
					setTimeout(()=>{
						try{
							let x = successCallback(this.value)
					        resolvePromise(promise2,x,resolve,reject)
						}catch(e){
							reject(e)
						}
					
					},0)   
				})
				this.failCallback.push(()=>{
					setTimeout(()=>{
						try{
							let x = failCallback(this.reason)
					        resolvePromise(promise2,x,resolve,reject)
						}catch(e){
							reject(e)
						}
					
					},0)   
				})
			}
			
			});
			return promise2
		}
	
	static all(array){
		let result = []
		let index = 0
		return  new mypromise((resolve,reject)=>{
			function adddata(key,value){
				result[key] = value;
				index++;
				if(index === array.length){
					resolve(result)
				}
			}
			for(let i = 0;i<array.length;i++){
				let current = array[i]
				if(current instanceof mypromise){
					current.then(value=>adddata(i,value),reason=>reject(reason))
				}else{
					adddata(i,array[i])
				}
			}
			resolve(result)
		})
	}
	
	static resolve(value){
		if(value instanceof mypromise) return value;
		return new mypromise(resolve => resolve(value))
	}
	
	finally(callback){
	return 	this.then(value=>{
		return mypromise.resolve(callback()).then(()=>value)
		},reason=>{
		return mypromise.resolve(callback()).then(()=>{throw reason})
		})
	}
	catch(failCallback){
	return 	this.then(undefined,failCallback)
	}
	
	}
	function resolvePromise(promise2,x,resolve,reject){
		if(promise2 === x){
			return reject(new TypeError('bnyzj'))
		}
		if(x instanceof mypromise){		
			x.then(resolve,reject)
		}else{
			resolve(x)
		}
	}